<template>
  <time :datetime="isoDate">
    {{ formattedTime }}
  </time>
</template>

<script lang="ts" setup>
/**
 * 实时时间组件
 * @description 已解决水合问题，可用于代替 NuxtTime 组件
 * @see https://nuxt.com.cn/docs/4.x/api/components/nuxt-time 官方 NuxtTime 组件
 */

import { useDateFormat } from '@vueuse/core'

const props = defineProps({
  format: {
    type: String,
    default: 'YYYY-MM-DD HH:mm:ss'
  },
  mode: {
    type: String,
    default: 'Interval' //  Interval 中等精度 | AnimationFrame 高精度
  }
})

// 1. 通过 Nuxt Payload 获取 SSR 时间戳
const { payload } = useNuxtApp()
const now = ref(new Date())
if (import.meta.client) {
  now.value = new Date(payload.serverTime ? String(payload.serverTime) : Date.now()) // 复用SSR传递的时间
}

// 2. SSR 阶段将时间注入 Payload
if (import.meta.server) {
  payload.serverTime = new Date().toISOString()
}

// 3. 格式化逻辑（兼容 SSR/CSR）
const formattedTime = ref(useDateFormat(now.value, props.format).value)
const isoDate = computed(() => now.value.toISOString()) // ISO 标准时间，SEO 友好

const updateFormattedTime = () => {
  formattedTime.value = useDateFormat(now.value, props.format).value
}

// 4. 客户端更新逻辑
let timer: NodeJS.Timeout | null = null
let animationFrameId: number | null = null

function updateWithAnimationFrame() {
  now.value = new Date()
  updateFormattedTime()
  animationFrameId = requestAnimationFrame(updateWithAnimationFrame)
}

onMounted(() => {
  if (props.mode === 'Interval') {
    updateFormattedTime()
    timer = setInterval(() => {
      now.value = new Date()
      updateFormattedTime()
    }, 1000)
  } else {
    animationFrameId = requestAnimationFrame(updateWithAnimationFrame)
  }
})

onBeforeUnmount(() => {
  timer && clearInterval(timer)
  animationFrameId && cancelAnimationFrame(animationFrameId)
})
</script>
